package com.zh.common.view.web

import android.annotation.TargetApi
import android.app.Activity
import android.content.Intent
import android.content.pm.ActivityInfo
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.os.Message
import android.provider.MediaStore
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.webkit.JsResult
import android.webkit.ValueCallback
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.FrameLayout
import android.widget.ProgressBar
import androidx.appcompat.app.AlertDialog
import androidx.core.content.FileProvider
import androidx.core.view.isVisible
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.PermissionUtils
import com.zh.common.ktx.showTipsDialog
import com.zh.config.PerConfig
import java.io.File

open class IWebChromeClient(
    private val iWebView: WebView, private val webName: (String?) -> Unit,
    private val webIcon: (String?) -> Unit
) : WebChromeClient() {

    private val TAG = "IWebChromeClient"
    private var mCustomView: View? = null
    private var mCustomViewCallback: CustomViewCallback? = null

    private var contentUri: Uri? = null
    private val CHOOSE_REQUEST_CODE = 0x9001
    private var uploadMessage: ValueCallback<Uri?>? = null
    private var uploadMessageAboveL: ValueCallback<Array<Uri?>?>? = null

    var activity: Activity? = null
    var progress: ProgressBar? = null

    override fun onShowCustomView(view: View?, callback: CustomViewCallback) {
        super.onShowCustomView(view, callback)
        if (mCustomView != null) {
            callback.onCustomViewHidden()
        }
        mCustomView = view
        activity?.let {
            val decor = it.window.decorView as FrameLayout
            decor.addView(
                mCustomView, FrameLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT
                )
            )
        }
        iWebView.visibility = View.GONE
        mCustomViewCallback = callback
        needRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
    }

    override fun onHideCustomView() {
        super.onHideCustomView()
        iWebView.visibility = View.VISIBLE
        if (mCustomView != null) {
            mCustomView?.visibility = View.GONE
            mCustomViewCallback?.onCustomViewHidden()
            (iWebView.parent as ViewGroup).removeView(mCustomView)
            mCustomView = null
            needRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
            super.onHideCustomView()
        }
    }

    override fun onProgressChanged(view: WebView?, newProgress: Int) {
        super.onProgressChanged(view, newProgress)
        Log.i(TAG, "progress $newProgress%")
        progress?.isVisible = newProgress < 100
        progress?.progress = newProgress
    }

    override fun onReceivedTitle(view: WebView?, title: String?) {
        super.onReceivedTitle(view, title)
        Log.i(TAG, "onReceivedTitle $title")
        webName.invoke(title)
    }

    override fun onReceivedTouchIconUrl(
        view: WebView?,
        url: String?,
        precomposed: Boolean
    ) {
        super.onReceivedTouchIconUrl(view, url, precomposed)
        Log.i(TAG, "onReceivedTouchIconUrl $url")
        webIcon.invoke(url)
    }

    //For Android  >= 4.1
    fun openFileChooser(
        valueCallback: ValueCallback<Uri?>,
        acceptType: String?,
        capture: String?
    ) {
        uploadMessage = valueCallback
        openFileChooseProcess(resetTypes(acceptType))
    }

    // For Android >= 5.0
    override fun onShowFileChooser(
        webView: WebView?,
        filePathCallback: ValueCallback<Array<Uri?>?>,
        fileChooserParams: FileChooserParams?
    ): Boolean {
        uploadMessageAboveL = filePathCallback
        Log.d(TAG, "onShowFileChooser--")
        PermissionUtils.permission(*PerConfig.sdcard_camera.toTypedArray())
            .callback { isAllGranted, granted, deniedForever, denied ->
                if (isAllGranted) {
                    openFileChooseProcess(fileChooserParams?.acceptTypes)
                } else if (deniedForever.isNotEmpty()) {
                    iWebView.context.showTipsDialog("您需要前往应用权限设置存储空间、相机权限才能进行该操作，是否前往同意存储空间、相机权限？") {
                        PermissionUtils.launchAppDetailsSettings()
                    }
                } else if (denied.isNotEmpty()) {
                    iWebView.context.showTipsDialog("您需要同意存储空间、相机权限才能进行操作，是否同意？") {
                        PermissionUtils.permission(*denied.toTypedArray())
                            .callback { isAllGranted, granted, deniedForever, denied ->
                                if (isAllGranted) {
                                    openFileChooseProcess(fileChooserParams?.acceptTypes)
                                }
                            }.request()
                    }
                }
            }.request()
        return true
    }

    // <a target="_blank" />
    override fun onCreateWindow(
        view: WebView,
        isDialog: Boolean,
        isUserGesture: Boolean,
        resultMsg: Message
    ): Boolean {
        val newWebView = WebView(view.context)
        newWebView.webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
                val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
                activity?.startActivity(browserIntent)
                return true
            }
        }
        val transport = resultMsg.obj as WebView.WebViewTransport
        transport.webView = newWebView
        resultMsg.sendToTarget()
        return true
    }

    override fun onCloseWindow(window: WebView?) {
        super.onCloseWindow(window)
    }

    override fun onJsAlert(
        view: WebView?, url: String?, message: String?, result: JsResult
    ): Boolean {
        val builder = AlertDialog.Builder(iWebView.context)
        builder.setPositiveButton(
            "确定"
        ) { dialog, which -> result.confirm() }
        builder.setMessage(message)
        builder.setCancelable(false)
        builder.create().show()
        return true
    }

    private fun openFileChooseProcess(types: Array<String>?) {
        val i = Intent(Intent.ACTION_GET_CONTENT)
        i.addCategory(Intent.CATEGORY_OPENABLE)
        i.putExtra(Intent.EXTRA_MIME_TYPES, types)
        i.type = "*/*"
        activity?.startActivityForResult(i, CHOOSE_REQUEST_CODE)
    }

    private fun resetTypes(acceptTypes: String?): Array<String>? {
        var mimeTypes: Array<String>? = null
        if (!acceptTypes.isNullOrEmpty()) {
            mimeTypes =
                acceptTypes.split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
        }
        return mimeTypes
    }

    fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode == Activity.RESULT_OK) {
            when (requestCode) {
                CHOOSE_REQUEST_CODE -> {
                    if (uploadMessageAboveL != null) {
                        onActivityResultAboveL(requestCode, resultCode, data)
                    } else if (uploadMessage != null) {
                        var result =
                            if (data == null || resultCode != Activity.RESULT_OK) null else data.data
                        if (result == null && resultCode == Activity.RESULT_OK) { //
                            result = contentUri //result = Uri.fromFile(newFile);
                            Log.e("图片为空1:", "$data $result")
                        }
                        uploadMessage?.onReceiveValue(result)
                        uploadMessage = null
                    }
                }
            }
        } else {
            uploadMessageAboveL?.onReceiveValue(null)
            uploadMessageAboveL = null
        }
    }

    // 选择图片的结果的处理
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private fun onActivityResultAboveL(requestCode: Int, resultCode: Int, intent: Intent?) {
        if (requestCode != CHOOSE_REQUEST_CODE || uploadMessageAboveL == null) return
        var results: Array<Uri?>? = null
        if (resultCode == Activity.RESULT_OK) {
            if (intent != null) {
                val dataString = intent.dataString
                val clipData = intent.clipData
                if (clipData != null) {
                    results = arrayOfNulls(clipData.itemCount)
                    for (i in 0 until clipData.itemCount) {
                        val item = clipData.getItemAt(i)
                        results[i] = item.uri
                    }
                }
                results = if (dataString != null) {
                    arrayOf<Uri?>(Uri.parse(dataString))
                } else {
                    arrayOf<Uri?>(contentUri)
                }
            } else {
                results = arrayOf<Uri?>(contentUri)
            }
        }
        uploadMessageAboveL?.onReceiveValue(results)
        uploadMessageAboveL = null
    }

    // Android7调用相机
    private fun getCameraIntent(): Intent? {
        val imagePath: File =
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
        if (!imagePath.exists()) {
            imagePath.mkdirs()
        }
        var intent: Intent? = null
        activity?.let {
            val provider: String = activity?.packageName + ".fileprovider"
            val newFile = File(imagePath, "${System.currentTimeMillis()}.jpg")
            contentUri = FileProvider.getUriForFile(it, provider, newFile)
            intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
            intent?.putExtra(MediaStore.EXTRA_OUTPUT, contentUri)
        }
        return intent
    }

    private fun needRequestedOrientation(orientation: Int) {
        LogUtils.e("needRequestedOrientation: $orientation")
        activity?.requestedOrientation = orientation
    }
}